#include "Candidate.h"

namespace cm_nat
{
    Candidate::Candidate():m_local_preference(0), m_network(0),m_foundation(0),m_port(0),m_rel_port(0)
    {

    }

    Candidate::~Candidate()
    {

    }

    void Candidate::setLocalPrefernce(UInt32 localPref)
    {
        m_local_preference = localPref;
    }

    UInt32 Candidate::computePriority()
    {
        UInt32 prority = (2^0)*(256-m_component); 
        
        UInt8 preference=0;
        if( m_type == "host"){
            preference = 126;
        }else if( m_type == "prflx"){
            preference = 110;
        }else if( m_type == "srflx" ){
            preference = 100;
        }else{
            preference = 0;
        }

        //compute type preference
        prority += (2^24)*preference;
        
        //compute local preference
        prority += (2^8)*m_local_preference;

        return prority;
    }

    cm_xmpp::Tag* Candidate::tag()
    {
        Tag* p_tag = new Tag("candidate");

        p_tag->addAttribute("component", m_component );
        p_tag->addAttribute("foundation", m_foundation );
        p_tag->addAttribute("generation",m_generation);
        p_tag->addAttribute("network",m_network);
        p_tag->addAttribute("id",m_id);
        p_tag->addAttribute("ip",m_ip);
        p_tag->addAttribute("port",m_port);
        p_tag->addAttribute( "priority", (long)m_priority); //cast to long may cause error
        p_tag->addAttribute("type", m_type );

        p_tag->addAttribute("rel-addr",m_rel_addr);
        if( !m_rel_addr.empty()){
            p_tag->addAttribute("rel-port", m_rel_port);
        }
        
        return p_tag;
    }

    bool Candidate::parse(const Tag* p_tag)
    {
        if( p_tag->name() != "candidate" )
            return false;

        m_component = NumberParser::parseUnsigned( p_tag->findAttribute("component") );
        m_foundation = NumberParser::parseUnsigned( p_tag->findAttribute("foundation") );
        m_generation = NumberParser::parseUnsigned( p_tag->findAttribute("generation") );
        m_network = NumberParser::parseUnsigned( p_tag->findAttribute("network") );
        m_id = p_tag->findAttribute("id");
        m_ip = p_tag->findAttribute("ip");
        m_port = NumberParser::parseUnsigned( p_tag->findAttribute("port") );
        m_priority = NumberParser::parseUnsigned( p_tag->findAttribute("priority") );
        m_type = p_tag->findAttribute("type");

        m_rel_addr = p_tag->findAttribute("rel-addr");
        if( !m_rel_addr.empty() ){
            m_rel_port = NumberParser::parseUnsigned( p_tag->findAttribute("rel-port") );
        }

        return true;
    }

    Candidate* Candidate::clone()
    {
        Candidate* p_clone = new Candidate;
        p_clone->m_component = m_component;
        p_clone->m_foundation = m_foundation;
        p_clone->m_generation = m_generation;
        p_clone->m_network = m_network;
        p_clone->m_id = m_id;
        p_clone->m_ip = m_ip;
        p_clone->m_port = m_port;
        p_clone->m_priority = m_priority;
        p_clone->m_type = m_type;
        p_clone->m_rel_addr = m_rel_addr;
        p_clone->m_rel_port = m_rel_port;

        return p_clone;
    }
}